<?php


namespace App\Models\CacheModel\lucky;


use App\Models\CacheModel\MonthFortune;
use app\common\lib\Util;
use App\Models\Api\BaseCache;
use think\Cache;
use think\Db;
use think\Log;
use AstroTool\Cache\CacheManage;

class AppLuckyTaskRecord extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.app_lucky_task_record';

    protected $cacheModel = 'lucky_planet.task_record';

    public $MaxSignInNum = 3; // 每日最大签到次数
    public $SignInInterval = 14400; // 签到时间间隔 3600*4

    /**
     * 获取 APP 首页 是否有领取任务小红点
     * @param int $uid
     * @return int
     * @throws \Exception
     */
    public function getIndexIsNew(int $uid)
    {
        $date = date('Ymd');

        if (Util::CheckAppVersion('2.9.7') !== '大')
        {   // 获取幸运星 领取信息
            $userLuckyChangeRecordModel = new AppUserLuckyChangeRecord();
            $signInInfo = $userLuckyChangeRecordModel->getUserSignInfoByToday($uid, $date);
            $status = 0;
            $lastTime = 0;
            if ($signInInfo['num'] < $this->MaxSignInNum)
            {
                $status = 1;
                $t = $signInInfo['time'] + $this->SignInInterval - time();
                $lastTime = $t > 0 ? $t : 0;
            }

            if ($status === 1 && $lastTime === 0)
            {
                return 1;
            }
        }
        $luckyTaskConfig = config('lucky_task');
        // 每日任务
        $everydaySuccessData = $this->getEverydayTaskSuccessData($uid, $date);  // 数据格式 任务ID=>1（待领取）｜2（已领取）
        foreach ($everydaySuccessData as $luckTaskIdItem => $item)
        {
            if (in_array($luckTaskIdItem, $luckyTaskConfig['everyday'], true) && (int)$item === 1)
            {
                return 1;
            }
        }
        // 其他任务
        $otherSuccessData = $this->getOtherTaskSuccessData($uid); // 数据格式 任务ID=>1（待领取）｜2（已领取）
        foreach ($otherSuccessData as $item)
        {
            if ((int)$item === 1)
            {
                return 1;
            }
        }

        // 获取 所有任务 信息
        $upgradeSuccessData = $this->getUpgradeTaskSuccessData($uid, $date); // 数据格式 任务ID=>['day'=>1(连续完成天数）,'type'=>1（未领取）｜2（已领取）]
        foreach ($luckyTaskConfig['upgrade'] as $taskId)
        {
            $taskInfo = $luckyTaskConfig['task_list'][$taskId];
            $day = $upgradeSuccessData[$taskId]['day'] ?? 0;
            if ($day >= $taskInfo['day'] && $upgradeSuccessData[$taskId]['type'] == 1)
            {
                return 1;
            }
        }
        return 0;
    }

    /**
     * 获取幸运星 任务列表
     * @param int $uid
     * @param int $rid
     * @return array[]
     * @throws \Exception
     */
    public function getTaskList(int $uid, int $rid)
    {
        $date = date('Ymd');
        // 获取 所有任务 信息
        $luckyTaskConfig = config('lucky_task');
        // 获取占星师 完成任务信息 获取用户完成任务信息
        $everydaySuccessData = $this->getEverydayTaskSuccessData($uid, $date);  // 数据格式 任务ID=>1（待领取）｜2（已领取）
        $upgradeSuccessData = $this->getUpgradeTaskSuccessData($uid, $date); // 数据格式 任务ID=>['day'=>1(连续完成天数）,'type'=>1（未领取）｜2（已领取）]
        $otherSuccessData = $this->getOtherTaskSuccessData($uid); // 数据格式 任务ID=>1（待领取）｜2（已领取）
        // 重组数据
        $taskInfo = null;
        $everydayData = []; // 每日任务信息
        foreach ($luckyTaskConfig['everyday'] as $taskId)
        {
            if ($taskId === 7 && Util::CheckAppVersion('2.9.1') === '小')
            {
                continue;
            }
            if ($taskId === 4 && Util::CheckAppVersion('2.9.7') === '大')
            {   // 大于2.9.7版本 去除每日运势日记任务
                continue;
            }
            $taskInfo = $luckyTaskConfig['task_list'][$taskId];
            if (!$taskInfo['is_show'])
            {
                continue;
            }
            if (isset($everydaySuccessData[$taskId]))
            {
                if ($everydaySuccessData[$taskId] == 1)
                {
                    $btnText = '领取';
                    $btnType = 2;
                } else
                {
                    $btnText = '已完成';
                    $btnType = 0;
                }
            } else
            {
                $btnText = '前往';
                $btnType = 1;
            }
            $everydayData[] = [
                'id' => $taskId,
                'title' => $taskInfo['name'],
                'img' => $taskInfo['img'],
                'des' => '幸运星 x' . $taskInfo['lucky_num'], // 幸运星数量服务器直接在这里面带着
                'btn_text' => $btnText,
                'btn_type' => $btnType, // 0=>文字按钮款式（已完成）, 1=>白底青字的款式（前往、进行中）,2=>青底白字款式（领取）
                'target' => $taskInfo['target'],
                'link' => $taskInfo['link'], // 可能为空，为空的时候不跳转
            ];
        }
        $upgradeData = []; // 每日任务信息
        foreach ($luckyTaskConfig['upgrade'] as $taskId)
        {
            $taskInfo = $luckyTaskConfig['task_list'][$taskId];
            $day = $upgradeSuccessData[$taskId]['day'] ?? 0;
            if ($day >= $taskInfo['day'])
            {
                $day = $taskInfo['day'];
                if ($upgradeSuccessData[$taskId]['type'] == 1)
                {
                    $btnText = '领取';
                    $btnType = 2;
                } else
                {
                    $btnText = '已完成';
                    $btnType = 0;
                }

            } else
            {
                $btnText = '进行中';
                $btnType = 1;
            }

            $upgradeData[] = [
                'id' => $taskId,
                'title' => "{$taskInfo['name']}（{$day}/{$taskInfo['day']}）",
                'img' => $taskInfo['img'],
                'des' => '幸运星 x' . $taskInfo['lucky_num'], // 幸运星数量服务器直接在这里面带着
                'btn_text' => $btnText,
                'btn_type' => $btnType, // 0=>文字按钮款式（已完成）, 1=>白底青字的款式（前往、进行中）,2=>青底白字款式（领取）
                'target' => $taskInfo['target'],
                'link' => $taskInfo['link'], // 可能为空，为空的时候不跳转
            ];
        }
        $otherData = []; // 其他任务信息
        foreach ($luckyTaskConfig['other'] as $taskId)
        {
            $taskInfo = $luckyTaskConfig['task_list'][$taskId];
            if (isset($otherSuccessData[$taskId]) && $otherSuccessData[$taskId] == 1)
            {
                $btnText = '领取';
                $btnType = 2;
            } else
            {
                $btnText = '前往';
                $btnType = 1;
            }
            if ($taskInfo['link'] === 'fortune_for_month')
            {   // 跳转月运  fortune_for_month?time=2022-5&need_auth=1
                $now_date = date('Y-m-d');
                [$now_year, $now_month, $now_day] = explode('-', $now_date);
                $isLock = false;    // 是否解锁月运
                if ($rid)
                {
                    $unlockMonths = (new MonthFortune())->getReocdeFortuneUnlockMonths($rid);
                    $isLock = in_array($now_year . '-' . $now_month, $unlockMonths, true);
                }
                //用户在本月25号至月底 点击解锁月运， 直接跳转至下月月运详情
                if ($now_day > 24)
                {
                    if ((int)$now_month === 12)
                    {
                        // 若未解锁当前运势，则跳转至下一年
                        if (!$isLock)
                        {
                            ++$now_year;
                            $now_month = 1;
                        }
                    } else
                    {
                        // 若未解锁当前运势，则跳转至下月
                        if (!$isLock)
                        {
                            ++$now_month;
                        }
                    }
                }
                $time = $now_year . '-' . $now_month;

                $taskInfo['link'] = "fortune_for_month?rid={$rid}&time={$time}&need_auth=1";
            }

            if ($taskId === 201 && Util::IsHuawei())
            {
                $taskInfo['name'] = '解锁报告';
            }
            $otherData[] = [
                'id' => $taskId,
                'title' => $taskInfo['name'],
                'img' => $taskInfo['img'],
                'des' => '幸运星 x' . $taskInfo['lucky_num'], // 幸运星数量服务器直接在这里面带着
                'btn_text' => $btnText,
                'btn_type' => $btnType, // 0=>文字按钮款式（已完成）, 1=>白底青字的款式（前往、进行中）,2=>青底白字款式（领取）
                'target' => $taskInfo['target'],
                'link' => $taskInfo['link'], // 可能为空，为空的时候不跳转
            ];
        }

        return [
            'everyday' => $everydayData,
            'upgrade' => $upgradeData,
            'other' => $otherData
        ];
    }

    /**
     * 获取每日任务 完成信息
     * @param int $uid
     * @param string $date
     * @return array
     * @throws \Exception
     */
    public function getEverydayTaskSuccessData(int $uid, string $date)
    {
        $resData = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':' . $date)->setCacheTime(86400)
            ->getDataAndSet(function () use ($uid, $date)
            {
                try
                {
                    $time = strtotime($date);  // 当天零点时间戳
                    $tomorrowTime = $time + 86400;  // 明天零点时间

                    $resData = $this->where('uid', $uid)->where('task_type', 1)
                        ->where('create_time', '>=', $time)
                        ->where('create_time', '<', $tomorrowTime)
                        ->select();
                    $d = [0 => 0];
                    foreach ($resData as $item)
                    {
                        $d[$item['task_id']] = (int)$item['status'] === 1 ? 1 : 2;
                    }

                    return $d;
                }
                catch (\Exception $e)
                {
                    return [0 => 0];
                }
            });

        unset($resData[0]);
        return $resData;
    }

    /**
     * 每日任务完成
     * @param int $uid
     * @param string $date
     * @param int $taskId
     * @return bool
     */
    public function setEverydayTaskSuccess(int $uid, string $date, int $taskId)
    {
        try
        {
            $taskIds = config('lucky_task.everyday');
            $ids = $this->where(['uid' => $uid, 'task_type' => 1, 'date' => $date])->whereIn('task_id', $taskIds)->column('task_id');
            $ids[] = $taskId;
            $ids = array_unique($ids);
            $idsSum = array_sum($ids);

            if (Util::CheckAppVersion('2.9.1') === '小')
            {
                foreach ($taskIds as $k => $taskIdItem)
                {
                    if ($taskIdItem == 7) unset($taskIds[$k]);
                }
            }

            if (Util::CheckAppVersion('2.9.7') === '大')
            {
                foreach ($taskIds as $k => $taskIdItem)
                {
                    if ($taskIdItem == 4) unset($taskIds[$k]);
                }
            }

            if ($idsSum === array_sum($taskIds) || $idsSum === 16)
            {   // 完成 了今日 所有的每日任务
                CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':upgrade:2')->setCache([$date => $date]);
            }

            $this->insert([
                'uid' => $uid,
                'task_id' => $taskId,
                'task_type' => 1,
                'status' => 1,
                'date' => $date,
                'create_time' => time(),
                'give_time' => 0
            ]);

            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':' . $date)->setCacheTime(86400)->setCache([$taskId => 1]);
        }
        catch (\Exception $e)
        {
            Log::write('问答 AppLuckyTaskRecord model => setEverydayTaskSuccess()异常：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error');
            return false;
        }
        return true;
    }

    /**
     * 每日任务完成 幸运星已领取
     * @param int $uid
     * @param string $date
     * @param int $taskId
     * @throws \Exception
     */
    public function everydayTaskSuccessSetGive(int $uid, string $date, int $taskId)
    {
        $this->where(['uid' => $uid, 'task_id' => $taskId, 'task_type' => 1, 'create_time' => ['>=', strtotime($date)]])->update(['status' => 3]);

        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':' . $date)->setCacheTime(86400)->setCache([$taskId => 2]);
    }

    /**
     * 获取升级任务完成信息  任务ID=>['day'=>1(连续完成天数）,'type'=>1（未领取）｜2（已领取）]
     * @param int $uid
     * @param string $date
     * @return array
     * @throws \Exception
     */
    public function getUpgradeTaskSuccessData(int $uid, string $date)
    {
        // 升级任务签到 完成的日期
        $resData1 = $this->getEvertDaySignData($uid, $date);
        unset($resData1[0]);
        // 升级任务 所有每日任务 完成的日期
        $resData2 = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':upgrade:2')->getDataAndSet(function () use ($uid, $date)
        {
            try
            {
                $time = strtotime('-7 day ' . $date);
                $taskIds = config('lucky_task.everyday');
                $datas = $this->where(['uid' => $uid, 'task_type' => 1, 'task_id' => ['in', $taskIds], 'create_time' => ['>=', $time]])->column('task_id,date', 'id');
                $d = [];
                foreach ($datas as $dataItem)
                {
                    $d[$dataItem['date']][] = $dataItem['task_id'];
                }

                $da = [0 => 0];
                foreach ($d as $dt => $item)
                {
                    $item = array_unique($item);
                    $idsSum = array_sum($item);
                    if ($idsSum === array_sum($taskIds) || $idsSum === 22)
                    {
                        $da[$dt] = $dt;
                    }
                }
                return $da;
            }
            catch (\Exception $e)
            {
                return [0 => 0];
            }
        });
        unset($resData2[0]);
        // 升级任务领取最后日期 记录 【task_id=>date】
        $resData3 = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':upgrade:give')->getDataAndSet(function () use ($uid, $date)
        {
            try
            {
                $time = strtotime('-7 day ' . $date);
                $taskIds = config('lucky_task.upgrade');
                $d = Db::table('wechat_backup_07_18_14_43_00.app_user_lucky_change_record')->where(['uid' => $uid, 'type' => 1, 'task_id' => ['in', $taskIds], 'create_time' => ['>=', $time]])
                    ->group('task_id')->column('max(create_time) as create_time', 'task_id');
                $da = [0 => 0];
                foreach ($d as $taskId => $item)
                {
                    $da[$taskId] = date('Ymd', $item);
                }
                return $da;
            }
            catch (\Exception $e)
            {
                return [0 => 0];
            }
        });
        unset($resData3[0]);
        // 获取  7天内 日期
        $sevenDates = [$date];
        for ($i = 1; $i <= 7; $i++)
        {
            $sevenDates[] = date('Ymd', strtotime("-{$i} day " . $date));
        }

        $taskConfig = config('lucky_task');
        $resData4 = [];
        foreach ($sevenDates as $key => $dateItem)
        {
            if ($key === 0)
            {
                foreach ($taskConfig['upgrade'] as $taskId)
                {
                    $d = $taskConfig['task_list'][$taskId]['type'] === 1 ? $resData1 : $resData2;

                    $day = isset($d[$dateItem]) ? 1 : 0;

                    $resData4[$taskId] = [
                        'is_over' => false,
                        'day' => $day,
                        'type' => isset($resData3[$taskId]) && $resData3[$taskId] === $dateItem ? 2 : 1,
                    ];
                }
            } else
            {
                foreach ($taskConfig['upgrade'] as $taskId)
                {
                    if ($resData4[$taskId]['is_over'])
                    {
                        continue;
                    }
                    $d = $taskConfig['task_list'][$taskId]['type'] === 1 ? $resData1 : $resData2;
                    if (!isset($d[$dateItem]) || (isset($resData3[$taskId]) && $resData3[$taskId] === $dateItem))
                    {
                        $resData4[$taskId]['is_over'] = true;
                    } else
                    {
                        $resData4[$taskId]['day'] += 1;
                    }
                }
            }
        }

        $retData = [];
        foreach ($resData4 as $taskId => $item)
        {
            $retData[$taskId] = [
                'day' => $item['day'] >= $taskConfig['task_list'][$taskId]['day'] ? $taskConfig['task_list'][$taskId]['day'] : $item['day'],
                'type' => $item['type']
            ];
        }

        return $retData;
    }

    /**
     * 升级 任务领取 记录
     * @param int $uid
     * @param string $date
     * @param int $taskId
     * @throws \Exception
     */
    public function upgradeTaskSuccessSetGive(int $uid, string $date, int $taskId)
    {
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':upgrade:give')->setCache([$taskId => $date]);
    }

    /**
     * 获取 其他任务完成信息
     * @param int $uid
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getOtherTaskSuccessData(int $uid)
    {
        $resData = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':other')->getDataAndSet(function () use ($uid)
        {
            try
            {
                $subQuery = $this->table('wechat_backup_07_18_14_43_00.app_lucky_task_record')->where(['uid' => $uid, 'task_type' => 3])->group('task_id')->field('max(id) as id')->buildSql();

                $resData = $this->where('id', 'IN', function ($query) use ($subQuery)
                {
                    $query->table($subQuery . ' tmp')->field('id');
                })->where('status', 1)->column('task_id');

                $d = [0 => 0];
                foreach ($resData as $taskId)
                {
                    $d[$taskId] = 1;
                }

                return $d;
            }
            catch (\Exception $e)
            {
                return [0 => 0];
            }
        });
        unset($resData[0]);

        return $resData;
    }

    /**
     * 其他任务完成
     * @param int $uid
     * @param int $taskId
     * @param string $orderId
     * @return bool
     */
    public function setOtherTaskSuccess(int $uid, int $taskId, string $orderId)
    {
        try
        {
            $luckyTaskConfig = config('lucky_task');
            if ($taskId === 200)    // task_id=200 发布悬赏问答
            {   // 同时完成 每日任务的发布问答
                $date = date('Ymd');
                $taskSuccessInfo = $this->getEverydayTaskSuccessData($uid, $date);

                if (!isset($taskSuccessInfo[5]))  // task_id= 5 发布问答
                {   // 任务 未完成 => 去完成
                    $this->setEverydayTaskSuccess($uid, $date, 5);  // task_id= 5 发布问答
                }
            }

            if (!in_array($taskId, $luckyTaskConfig['other'], true))
            {
                Log::write('问答 AppLuckyTaskRecord model => setOtherTaskSuccess()异常：taskId=' . $taskId, 'error');
                return false;
            }

            // 过期之前未领取的当前任务
            $this->where(['uid' => $uid, 'task_id' => $taskId, 'status' => 1])->update(['status' => 2]);
            // 写入 待领取 数据
            $this->insert([
                'uid' => $uid,
                'task_id' => $taskId,
                'task_type' => 3,
                'status' => 1,
                'date' => date('Ymd'),
                'create_time' => time(),
                'give_time' => 0
            ]);

            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':other')->setCache([$taskId => 1]);
            $toastTitle = $luckyTaskConfig['task_list'][$taskId]['toast_name'];
            if ($taskId === 201 && Util::IsHuawei())
            {
                $toastTitle = '解锁报告';
            }
            // 记录临时任务完成提示信息
            Cache::set('lucky_other_task:' . $orderId, [
                "title" => $toastTitle,
                "img" => $luckyTaskConfig['task_list'][$taskId]['img'],
                "des" => "x{$luckyTaskConfig['task_list'][$taskId]['lucky_num']}可领取"
            ], 86400);
        }
        catch (\Exception $e)
        {
            Log::write('幸运星任务完成 AppLuckyTaskRecord model => setOtherTaskSuccess()异常：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error');
            return false;
        }

        return true;
    }

    /**
     *  其他任务 领取 记录
     * @param int $uid
     * @param int $taskId
     * @return bool
     */
    public function otherTaskSuccessSetGive(int $uid, int $taskId)
    {
        try
        {
            // 未领取状态 更新至已领取
            $this->where(['uid' => $uid, 'task_id' => $taskId, 'status' => 1])->update(['status' => 3]);
            // 记录 已领取
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':other')->setCache([$taskId => 2]);
        }
        catch (\Exception $e)
        {
            Log::write('幸运星任务领取 AppLuckyTaskRecord model => otherTaskSuccessSetGive()异常：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error');
            return false;
        }

        return true;
    }

    /**
     * @param int $uid
     * @param string $date
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getEvertDaySignData(int $uid, string $date)
    {
        $resData1 = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':upgrade:1')->getDataAndSet(function () use ($uid, $date)
        {
            try
            {
                $time = strtotime('-7 day ' . $date);
                $d = Db::table('wechat_backup_07_18_14_43_00.app_user_lucky_change_record')->where(['uid' => $uid, 'type' => 1, 'task_id' => ['in', [1, 8]], 'create_time' => ['>=', $time]])->column('create_time');
                $da = [0 => 0];
                foreach ($d as $item)
                {
                    $e = date('Ymd', $item);
                    $da[$e] = $e;
                }
                return $da;
            }
            catch (\Exception $e)
            {
                return [0 => 0];
            }
        });
        return $resData1;
    }
}
